package pers.duorhs.app.service;

import com.corundumstudio.socketio.SocketIOServer;
import io.socket.client.Socket;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;
import pers.duorhs.common.redis.RedisConstance;
import pers.duorhs.common.socket.SocketClientHandler;
import pers.duorhs.common.socket.SocketConstance;
import pers.duorhs.common.socket.SocketData;
import pers.duorhs.common.socket.SocketServerHandler;
import pers.duorhs.common.socket.service.AppSocketService;
import pers.duorhs.common.socket.service.CsrSocketService;
import pers.duorhs.common.util.RedisUtil;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author Duorhs
 * @date 2022/5/9 13:52
 */
@Service
@Slf4j
@AllArgsConstructor
@DubboService
public class AppSocketServiceImpl implements AppSocketService {
    private final SocketServerHandler serverHandler;
    private final SocketClientHandler clientHandler;
    private final RedisUtil redisUtil;
    private SocketIOServer socketIOServer;
    @DubboReference
    private CsrSocketService csrSocketService;

    /**
     * 客户登录
     *
     * @param customer
     */
    @Override
    public void login(String customer) {
        clientHandler.login(customer, SocketConstance.APP_ONLINE);
        log.info("客户 {} 开始排队", customer);
        redisUtil.zAdd(RedisConstance.QUEUE, customer, System.currentTimeMillis());
        csrSocketService.checkQueue();
    }

    /**
     * 给坐席端推送消息
     *
     * @param customer
     * @param msg
     */
    @Override
    public void push(String customer, String msg) {
        SocketData<String> socketData = new SocketData<>();
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        map.put("customer", customer);
        socketData.setHead(map);
        socketData.setBody(msg);
        csrSocketService.pushToCsrClient(socketData);
    }

    /**
     * 结束业务
     *
     * @param customer
     */
    @Override
    public void end(String customer) {
        csrSocketService.workDone(customer);
        socketIOServer.getRoomOperations(SocketConstance.APP_ONLINE).sendEvent(Socket.EVENT_DISCONNECT, customer);
    }

    /**
     * 推送信息到App前端
     *
     * @param data
     */
    @Override
    public void pushToAppClient(SocketData<String> data) {
        Object employee = data.getHead().get("employee");
        String customer = findCustomerByEmployee((String) employee);
        data.getHead().put("customer", customer);
        socketIOServer.getRoomOperations(SocketConstance.APP_ONLINE).sendEvent(SocketConstance.EVENT, data);
    }

    private String findCustomerByEmployee(String employee) {
        Cursor<Map.Entry<Object, Object>> cursor = redisUtil.hScan(RedisConstance.WORKING_RELATION, ScanOptions.NONE);
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> entry = cursor.next();
            if (entry.getKey().equals(employee)) {
                return (String) entry.getValue();
            }
        }
        log.info("找不到 {} 对应的客户", employee);
        return null;
    }


}
